 /*      SVMachine.h
 *
 *      Copyright 2009-2010 virpool <virpool@ukrpost.ua>
 *
 *      This program is free software; you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation; either version 2 of the License, or
 *      (at your option) any later version.
 *
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *
 *      You should have received a copy of the GNU General Public License
 *      along with this program; if not, write to the Free Software
 *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 *      MA 02110-1301, USA.
 */

#ifndef __SVMACHINE_H_
#define __SVMACHINE_H_

#include <iostream>
#include <list>
#include <string.h>
#include <cstdio>
#include <sys/types.h>

#include "SClassArray.h"
#include "SClassInteger.h"
#include "SClassFloat.h"
#include "SClassString.h"
#include "SClassBoolean.h"
#include "SClassObject.h"
#include "SClassHash.h"
#include "SClassFile.h"
#include "SGarbageCollector.h"

const unsigned short s_default_deep = 1024;

class SVMachine
{
	static SVMachine *__instance;
	SVMachine();
	
	SRegistryObj **global;
	unsigned int level;
	unsigned int max_level;
	
	list<std::string> pbuf; // special for operations with parameters
	list<std::string> stdout_buf; // special for very long output (puts, put etc.). analog of stringbuilder
	param_list args;
	list<void*> garbage;
	
	bool is_spec_op_flag;
	
	bool is_operation_com;

	bool is_get_object;
	bool is_break;

	unsigned short e_deep;
	
	double expr_val[s_default_deep][s_default_deep];
	std::string expr_val_str[s_default_deep][s_default_deep];
	bool expr_val_bool;
	unsigned int expr_deep[s_default_deep];
	unsigned int expr_deep_str[s_default_deep];
	list<s_command*> commands;
	
	s_command *cur_comm;
	
	unsigned short comm_deep;
	list<s_command*> comm_cache[s_default_deep];
	
	s_methods t_integer;
	s_methods t_float;
	s_methods t_string;
	
	SObject *value[255];
	unsigned short value_deep;
	
	bool args_flags[s_default_deep];
	unsigned char args_flags_p;
	
	bool test_parent();
	
	void new_object();
	void create_object(std::string name, SRegistryObj *reg, s_param *val = NULL);
	void input();
	void operation_handler();
	void put_operation();
	void expression_operarion();
	void expression_calc();
	void prepare_expr_array();
	void id_dotlist_handler();
	void expr_post_handler();
	void expr_array_handler();
	void if_operation();
	void while_operation();
	void for_operation_smpl();
	void for_operation_foreach();
	void for_cont_operation();
	void method_handler();
	void call_method(SObject *obj, s_command *method, bool is_args = false);
	bool expr_test_string();
	bool check_object(std::string name, SRegistryObj *reg);
	SObject* find_object(std::string name);
	s_param get_last_arg();
	bool get_subobject(std::string *objname, SObject *&obj2);
	bool params_handler(int deep, std::string *objname, SObject *&obj2);
	void delete_operation();
	void operation(bool is_string, bool is_params);
	void operation_expr(s_param &prm);
	void input_string(SObject *o);
	void put_out(bool _endl);
	
public:
	static SVMachine* GetInstance();
	static void Release(); // Window's COM hello ! = )
	
	~SVMachine();
	
	void SetGlobal(SRegistryObj **global);
	
	void AddCommand(s_command *command) { commands.push_back(command); }
	
	bool Execute();
};

#endif
